
package analiseSintatica.Regras.Expressoes;

import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import AnaliseLexicaFinal.EstruturaDeDados.Token;
import java.util.ArrayList;
import java.util.LinkedList;

import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.Regra;
import analiseSintatica.estruturadados.NoArvore;

/**
 * Contem as regras para a analise sintatica
 * @author nathy
 */
public class RegraElementoStruct extends Regra {


    protected static Regra instancia;
    protected static String estrutura = "<elemento_struct> ::= . identificador | -> identificador";



    /**
     * Construtor privado necessario ao singleton
     */
    private RegraElementoStruct() {
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraElementoStruct getInstance() {
        if (instancia == null) {
            instancia = new RegraElementoStruct();
        }
        return (RegraElementoStruct) instancia;
    }

    /**
     * Realiza analise sintatica
     * @param listaTokens - Tokens do codigo
     * @return - Arvore sintatica
     * @throws Exception
     */
    public NoArvore analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException{
    NoArvore naoterminalElemento = new NoArvore("<elemento>", false);
    if(listaTokens.getFirst().getLexema().equals("."))
        //N sei qual o nome desses tokens
       naoterminalElemento.adicionaFilho(reconheceLexema(listaTokens, listaTokens.getFirst().getToken() , ".",estrutura));
    else
       naoterminalElemento.adicionaFilho(reconheceLexema(listaTokens, listaTokens.getFirst().getToken() , "->",estrutura));
       naoterminalElemento.adicionaFilho(reconheceToken(listaTokens, "identificador",estrutura));
    return naoterminalElemento;
    }
    



    @Override
    protected void setPrimeiro() {
       //P<elemento_struct>  = "." U "->"
        this.primeiro.add(".");
        this.primeiro.add("->");

    }

    @Override
    protected void setSeguinte() {
        //S<elemento_struct>   = P<elemento_struct>   U S<elemento_variavel>-e  U S<elemento_var>
        this.seguinte.addAll(primeiro);
        /*this.seguinte = getUniao(RegraElementoStruct.getInstance().primeiro,
               RegraElementoVariavel.getInstance().getSeguinte());
        this.seguinte = getUniao(this.seguinte, RegraElementoVar.getInstance().getSeguinte());
        if(this.seguinte.contains("e")) this.seguinte.remove("e");*/
        seguinte.add("(");
        seguinte.add("{");
        seguinte.add("identificador");
        seguinte.add("numeroInteiro");
        seguinte.add("numeroFlutuante");
        seguinte.add("charconst");
        seguinte.add("++");
        seguinte.add("--");
        seguinte.add("&");
        seguinte.add("*");
        seguinte.add("+");
        seguinte.add("-");
        seguinte.add("<");
        seguinte.add("<=");
        seguinte.add(">");
        seguinte.add(">=");
        seguinte.add("==");
        seguinte.add("!=");
        seguinte.add("&&");
        seguinte.add(";");
        seguinte.add(",");
        seguinte.add("}");
        seguinte.add(")");
        this.seguinte.add("=");
    }


 


}
